package com.Controls;

import com.HMI.Main;
import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;

public class ClControl {
	// Controller parameters (for tuning)
	private static final double dblRef = 2.0; // Reference Cl value in ppm
	private static final double dblPGain = 0.6; // P control gain

	private static final double dblPpmStrk = 0.053; // Added ppm per stroke
	private static final int intTStrk = 30; // Signal time in ms for 1 stroke

	private static GpioController gpio = GpioFactory.getInstance();
	private static GpioPinDigitalOutput pin = gpio.provisionDigitalOutputPin(
			RaspiPin.GPIO_02, PinState.LOW);
	
	public static double Control(double dblClSensor) throws InterruptedException {
		// "Main" block
		double dblSensor; // Sensor reading in ppm
		double dblPpmExp; // Expected ppm rise from injection

		dblSensor = dblClSensor;
		dblPpmExp = Controller(dblSensor);

		return dblPpmExp;
	}

	private static double Controller(double dblSensor) throws InterruptedException {
		double dblError; // Difference between ref and sensor
		int intSignal; // Input to plant (# of strokes)

		dblError = dblRef - dblSensor;
		if (dblError < dblPpmStrk)
			dblError = dblPpmStrk/0.6;
		else if (dblError < 0)
			dblError = 0; // Assume no/minimal overshoot (not like we can do
							// anything about it)

		intSignal = (int) (dblPGain * dblError / dblPpmStrk); // Apply PGain% of
																// strokes
																// required to
																// equal the
																// error (min 1)

		Pump(intSignal);

		return (dblPpmStrk * intSignal);
	}

	private static void Pump(int intInput) throws InterruptedException {
		System.out.println("Pump Active: " + intInput + "Cycles");
		for (int i = 0; i < intInput; i++) {
			pin.high();
			Thread.sleep(intTStrk);
			pin.low();
			Thread.sleep(intTStrk * 3);
		}
	}
}
